﻿/*
-----------------------------------------------------------------------------------
<copyright file="Editor.js" company="Microsoft Corporation">
         (c) © 2016 Microsoft. All rights reserved.
    
</copyright>
---------------------------------------------------------------------------------
*/

function tabify() {
    $("#tabs").tabs();

    refreshTabs();
}

function refreshTabs() {
    $("#tabs").find(".ui-tabs-nav").sortable({
        axis: "x",
        stop: function () {
            $("#tabs").tabs("refresh");
        }
    });
    $("#tabList li").on("dblclick", function () {
        $(this).find("input").toggle().val($(this).find("a").html()).focus();
        $(this).find("a").toggle();
    });

    $("#tabList li").on("keydown blur dblclick", "input", function (e) {
        if (e.type == "keydown") {
            if (e.which == 13) {
                $(this).toggle();
                $(this).siblings("a").toggle().html($(this).val());
            }
            if (e.which == 38 || e.which == 40 || e.which == 37 || e.which == 39 || e.keyCode == 32) {
                e.stopPropagation();
            }

        }
        else if (e.type == "focusout") {
            if ($(this).css("display") == "inline-block") {
                $(this).toggle();
                $(this).siblings("a").toggle().html($(this).val());
            }
        }
        else {
            e.stopPropagation();
        }
    });
    $("#tabs").tabs("refresh");
}

var editors = [];
function replaceDOMElements() {
    $("#codeEditor0").remove();
    $(".tab").closest("li").remove();

    var iterations = parseInt(localStorage["numStored"]);

    for (var i = 0; i < iterations; i++) {
        var codeInfo = JSON.parse(localStorage["codeInfo" + i]);
        var newTabName = codeInfo["fileName"];
        var code = codeInfo["code"];
        var cursRow = codeInfo["cursRow"];
        var cursCol = codeInfo["cursCol"];

        makeTab(i, newTabName, code);

        editors[i].gotoLine(cursRow, cursCol);
    }

    beautify();
    refreshTabs();
}

function initializeDefaults() {
    initializeAce(0);

    editors[0].gotoLine(1, 0);
}

function createEditor() {
    var newIDNum = editors.length;
    var newTabName = prompt("What do you want to name the new tab?", "NewTab" + newIDNum);
    if (newTabName == "") {
        newTabName = "NewTab" + newIDNum;
    }
    else if (newTabName == null) {
        return;
    }

    newTabCode = "public class " + newTabName + " {\n\t//Enter code here...\n\t\n}";
    
    makeTab(newIDNum, newTabName, newTabCode);

    beautify();
    refreshTabs();
}

function beautify() {
    for (var i = 0; i < editors.length; i++) {
        var val = editors[i].session.getValue();
        var array = val.split(/\n/);
        array[0] = array[0].trim();
        val = array.join("\n");
        val = js_beautify(val);
        var cursPos = editors[i].getCursorPosition();
        editors[i].setValue(val);
        editors[i].gotoLine(cursPos.row + 1, cursPos.column);
    }
}

$("#tabs").delegate("span.ui-icon-closethick", "click", function () {
    if (editors.length > 1) {
        if (confirm("Are you sure you want to close this tab?")) {
            var panelId = $(this).closest("li").remove().attr("aria-controls");
            var removeIndex = removeEditor(panelId);
            editors.splice(removeIndex, 1);
            $("#" + panelId).remove();
        }
    } else {
        alert("Sory, unable to close; at least one editor must be open");
    }
    refreshTabs();
});

function removeEditor(removeId) {
    var removeEditor = ace.edit(removeId);
    removeEditor.destroy();
    var tabs = document.getElementById("tabs");
    var editorDivs = tabs.children;
    var editorCount;
    var firstEditor = true;
    for (var i = 0; i < editorDivs.length; i++) {
        if (firstEditor && editorDivs[i].id.includes("codeEditor")) {
            firstEditor = false;
            editorCount = 0;
        }
        if(editorDivs[i].getAttribute("id") == removeId) {
            return editorCount;
        } else {
            editorCount++;
        }
    }
    return -1;
}

function openFile(evt) {
    var f = evt.target.files[0];

    if (f) {
        var r = new FileReader();
        r.onload = function (e) {
            if (f.name.includes(".java")) {
                var contents = e.target.result;
                var tabName = f.name.replace(/.java/, "");
                newTabFromFile(tabName, contents);
            } else {
                alert("You can only insert .java files");
            }
        }
        r.readAsText(f);
    } else {
        alert("Failed to load file");
    }
}
document.getElementById("realOpenFile").addEventListener("change", openFile, false)

function newTabFromFile(newTabName, code) {
    var newIDNum = editors.length;

    makeTab(newIDNum, newTabName, code);

    beautify();
    refreshTabs();
}

function makeTab(numEditor, tabName, code) {
    var newEditor = document.createElement("div");
    newEditor.setAttribute("id", "codeEditor" + numEditor);
    newEditor.setAttribute("class", "edit");

    var editText = document.createTextNode(code);
    newEditor.appendChild(editText);

    var tabs = document.getElementById("tabs");
    tabs.insertBefore(newEditor, tabs.children[tabs.children.length - 1]);

    var newTab = document.createElement("li");
    var tabInput = document.createElement("input");
    tabInput.setAttribute("class", "txt");
    tabInput.setAttribute("type", "text");
    newTab.appendChild(tabInput);

    var tabLink = document.createElement("a");
    tabLink.setAttribute("href", "#codeEditor" + numEditor);
    tabLink.setAttribute("class", "tab");
    var tabText = document.createTextNode(tabName);
    tabLink.appendChild(tabText);
    newTab.appendChild(tabLink);

    var closeButton = document.createElement("span");
    closeButton.setAttribute("class", "ui-icon ui-icon-closethick");
    newTab.appendChild(closeButton);

    var tabList = document.getElementById("tabList");
    tabList.appendChild(newTab);

    initializeAce(numEditor);
}

function initializeAce(numEditor) {
    ace.require("ace/ext/language_tools");
    editors.push(ace.edit("codeEditor" + numEditor));
    editors[numEditor].setTheme("ace/theme/tomorrow_night_bright");
    editors[numEditor].getSession().setMode("ace/mode/java");
    editors[numEditor].setOptions({
        enableBasicAutocompletion: true,
        enableSnippets: true,
        enableLiveAutocompletion: true,
        wrap: true,
        showPrintMargin: false
    });
    editors[numEditor].$blockScrolling = Infinity;
    editors[numEditor].commands.addCommand({
        name: 'save',
        bindKey: { win: "Ctrl-S", "mac": "Cmd-S" },
        exec: function (editor) {
            saveAll();
        }
    });
}

function reset() {
    var currEditName = $("#tabList .ui-tabs-active a").text();
    var currEditId = $("#tabList .ui-tabs-active a").attr("href").replace("#", "");
    var currEdit = ace.edit(currEditId);
    currEdit.setValue("public class " + currEditName + " {\n\t//Enter code here...\n\t\n}");
    var tabSize = currEdit.getSession().getTabSize();
    currEdit.gotoLine(3, tabSize);
}

function downloadAll() {
    var preFolderName = prompt("What do you want to name the folder?", "JavaProject");
    if (preFolderName == "") {
        preFolderName = "JavaProject";
    }
    else if (preFolderName == null) {
        return;
    }
    folderName = preFolderName + ".zip";
    var code = [];
    var fileNames = [];
    $(".tab").each(function () {
        fileNames.push($(this).text());

        var preId = $(this).attr("href");
        var codeId = preId.slice(1);
        var codeVal = ace.edit(codeId).getValue();
        code.push(codeVal);
    });
    var zip = new JSZip();
    for (var i = 0; i < code.length; i++) {
        zip.file(fileNames[i] + ".java", code[i]);
    }
    zip.generateAsync({ type: "blob" })
    .then(function (content) {
        saveAs(content, folderName);
    });
}

function downloadCurrent() {
    var currEditName = $("#tabList .ui-tabs-active a").text();
    var currEditId = $("#tabList .ui-tabs-active a").attr("href").replace("#", "");
    var currEdit = ace.edit(currEditId);
    var code = currEdit.getValue();
    var fileName = currEditName + ".java";

    var file = new File([code], fileName);
    saveAs(file, fileName);
}

function saveAll() {
    if (typeof (Storage) !== "undefined") {
        localStorage.clear();
        localStorage.setItem("hasStoredItems", "yes");
        var tabList = document.getElementById("tabList");
        localStorage.setItem("numStored", tabList.children.length);

        $(".tab").each(function (index) {
            var fileName = $(this).text();

            var preId = $(this).attr("href");
            var codeId = preId.slice(1);
            var code = ace.edit(codeId).getValue();

            var cursorRow = ace.edit(codeId).getCursorPosition().row;
            var cursorCol = ace.edit(codeId).getCursorPosition().column;

            var codeInfoObj = { "code": code, "fileName": fileName, "cursRow": cursorRow + 1, "cursCol": cursorCol };
            localStorage.setItem("codeInfo" + index, JSON.stringify(codeInfoObj));
        });
        alert("Saved. Press enter or the spacebar to close this message");
    } else {
        alert("Failed to save")
    }
}